home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Meshwriter / dxf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  13.3 KB  |  310 lines

  1. /*
  2. **      $VER: dxf.c 1.00 (27.03.1999)
  3. **
  4. **      Creation date : 06.12.1998
  5. **
  6. **      Description       :
  7. **         Standart saver module for meshwriter.library.
  8. **         Saves the mesh as DXF ascii file.
  9. **
  10. **
  11. **      Written by Stephan Bielmann
  12. **
  13. */
  14.  
  15. /*************************** Includes *******************************/
  16.  
  17. /*
  18. ** Ansi C includes
  19. */
  20. #include <math.h>
  21.  
  22. /*
  23. ** Amiga includes
  24. */
  25. #include <dos/dos.h>
  26. #include <dos/stdio.h>
  27.  
  28. #include <clib/dos_protos.h>
  29. #include <clib/alib_stdio_protos.h>
  30.  
  31. /*
  32. ** Project includes
  33. */
  34. #include "meshwriter_private.h"
  35.  
  36. /*********************** Type definitions ***************************/
  37.  
  38. /*
  39. ** This struct is created just for storing AutoCAD default
  40. ** color palette table.
  41. */
  42. typedef struct {
  43.         UBYTE  red, green, blue;
  44. } DXFColor;
  45.  
  46. /*************************** Variables ******************************/
  47.  
  48. /*
  49. ** AutoCAD equivalent rgb colors.
  50. */
  51. static const DXFColor colorTbl[] = {
  52. {  0,  0,  0},{255,  0,  0},{255,255,  0},{  0,255,  0},{  0,255,255},{  0,  0,255},{255,  0,255},
  53. {255,255,255},{  0,  0,  0},{  0,  0,  0},{255,  0,  0},{255,128,128},{166,  0,  0},{166, 83, 83},
  54. {128,  0,  0},{128, 64, 64},{ 77,  0,  0},{ 77, 38, 38},{ 38,  0,  0},{ 38, 19, 19},{255, 64,  0},
  55. {255,159,128},{166, 41,  0},{166,104, 83},{128, 32,  0},{128, 80, 64},{ 77, 19,  0},{ 77, 48, 38},
  56. { 38, 10,  0},{ 38, 24, 19},{255,128,  0},{255,191,128},{166, 83,  0},{166,124, 83},{128, 64,  0},
  57. {128, 96, 64},{ 77, 38,  0},{ 77, 57, 38},{ 38, 19,  0},{ 38, 29, 19},{255,191,  0},{255,223,128},
  58. {166,124,  0},{166,145, 83},{128, 96,  0},{128,112, 64},{ 77, 57,  0},{ 77, 67, 38},{ 38, 29,  0},
  59. { 38, 33, 19},{255,255,  0},{255,255,128},{166,166,  0},{166,166, 83},{128,128,  0},{128,128, 64},
  60. { 77, 77,  0},{ 77, 77, 38},{ 38, 38,  0},{ 38, 38, 19},{191,255,  0},{223,255,128},{124,166,  0},
  61. {145,166, 83},{ 96,128,  0},{112,128, 64},{ 57, 77,  0},{ 67, 77, 38},{ 29, 38,  0},{ 33, 38, 19},
  62. {128,255,  0},{191,255,128},{ 83,166,  0},{124,166, 83},{ 64,128,  0},{ 96,128, 64},{ 38, 77,  0},
  63. { 57, 77, 38},{ 19, 38,  0},{ 29, 38, 19},{ 64,255,  0},{159,255,128},{ 41,166,  0},{104,166, 83},
  64. { 32,128,  0},{ 80,128, 64},{ 19, 77,  0},{ 48, 77, 38},{ 10, 38,  0},{ 24, 38, 19},{  0,255,  0},
  65. {128,255,128},{  0,166,  0},{ 83,166, 83},{  0,128,  0},{ 64,128, 64},{  0, 77,  0},{ 38, 77, 38},
  66. {  0, 38,  0},{ 19, 38, 19},{  0,255, 64},{128,255,159},{  0,166, 41},{ 83,166,104},{  0,128, 32},
  67. { 64,128, 80},{  0, 77, 19},{ 38, 77, 48},{  0, 38, 10},{ 19, 38, 24},{  0,255,128},{128,255,191},
  68. {  0,166, 83},{ 83,166,124},{  0,128, 64},{ 64,128, 96},{  0, 77, 38},{ 38, 77, 57},{  0, 38, 19},
  69. { 19, 38, 29},{  0,255,191},{128,255,223},{  0,166,124},{ 83,166,145},{  0,128, 96},{ 64,128,112},
  70. {  0, 77, 57},{ 38, 77, 67},{  0, 38, 29},{ 19, 38, 33},{  0,255,255},{128,255,255},{  0,166,166},
  71. { 83,166,166},{  0,128,128},{ 64,128,128},{  0, 77, 77},{ 38, 77, 77},{  0, 38, 38},{ 19, 38, 38},
  72. {  0,191,255},{128,223,255},{  0,124,166},{ 83,145,166},{  0, 96,128},{ 64,112,128},{  0, 57, 77},
  73. { 38, 67, 77},{  0, 29, 38},{ 19, 33, 38},{  0,128,255},{128,191,255},{  0, 83,166},{ 83,124,166},
  74. {  0, 64,128},{ 64, 96,128},{  0, 38, 77},{ 38, 57, 77},{  0, 19, 38},{ 19, 29, 38},{  0, 64,255},
  75. {128,159,255},{  0, 41,166},{ 83,104,166},{  0, 32,128},{ 64, 80,128},{  0, 19, 77},{ 38, 48, 77},
  76. {  0, 10, 38},{ 19, 24, 38},{  0,  0,255},{128,128,255},{  0,  0,166},{ 83, 83,166},{  0,  0,128},
  77. { 64, 64,128},{  0,  0, 77},{ 38, 38, 77},{  0,  0, 38},{ 19, 19, 38},{ 64,  0,255},{159,128,255},
  78. { 41,  0,166},{104, 83,166},{ 32,  0,128},{ 80, 64,128},{ 19,  0, 77},{ 48, 38, 77},{ 10,  0, 38},
  79. { 24, 19, 38},{128,  0,255},{191,128,255},{ 83,  0,166},{124, 83,166},{ 64,  0,128},{ 96, 64,128},
  80. { 38,  0, 77},{ 57, 38, 77},{ 19,  0, 38},{ 29, 19, 38},{191,  0,255},{223,128,255},{124,  0,166},
  81. {145, 83,166},{ 96,  0,128},{112, 64,128},{ 57,  0, 77},{ 67, 38, 77},{ 29,  0, 38},{ 33, 19, 38},
  82. {255,  0,255},{255,128,255},{166,  0,166},{166, 83,166},{128,  0,128},{128, 64,128},{ 77,  0, 77},
  83. { 77, 38, 77},{ 38,  0, 38},{ 38, 19, 38},{255,  0,191},{255,128,223},{166,  0,124},{166, 83,145},
  84. {128,  0, 96},{128, 64,112},{ 77,  0, 57},{ 77, 38, 67},{ 38,  0, 29},{ 38, 19, 33},{255,  0,128},
  85. {255,128,191},{166,  0, 83},{166, 83,124},{128,  0, 64},{128, 64, 96},{ 77,  0, 38},{ 77, 38, 57},
  86. { 38,  0, 19},{ 38, 19, 29},{255,  0, 64},{255,128,159},{166,  0, 41},{166, 83,104},{128,  0, 32},
  87. {128, 64, 80},{ 77,  0, 19},{ 77, 38, 48},{ 38,  0, 10},{ 38, 19, 24},{ 84, 84, 84},{118,118,118},
  88. {152,152,152},{187,187,187},{221,221,221},{255,255,255}
  89. };
  90.  
  91. /********************** Private functions ***************************/
  92.  
  93. /********************************************************************\
  94. *                                                                    *
  95. * Name         : magnitude                                           *
  96. *                                                                    *
  97. * Description  : Calculates the magnitude of a color vector.         *
  98. *                                                                    *
  99. * Arguments    : x,y,z : Color vector.                               *
  100. *                                                                    *
  101. * Return Value : Vector its magnitude.                               *
  102. *                                                                    *
  103. * Comment      :                                                     *
  104. *                                                                    *
  105. \********************************************************************/
  106. static ULONG magnitude(LONG x, LONG y, LONG z)
  107. {
  108.     return(sqrt(x*x + y*y + z*z));
  109. }
  110.  
  111. /********************************************************************\
  112. *                                                                    *
  113. * Name         : index2Color                                         *
  114. *                                                                    *
  115. * Description  : Converts a DXF color index into a RGB color.        *
  116. *                                                                    *
  117. * Arguments    : index : The color index.                            *
  118. *                                                                    *
  119. * Return Value : Vector its magnitude.                               *
  120. *                                                                    *
  121. * Comment      :                                                     *
  122. *                                                                    *
  123. \********************************************************************/
  124. static DXFColor index2Color(ULONG index)
  125. {
  126.     static DXFColor col;
  127.     
  128.     /*
  129.     ** Check range
  130.     */
  131.     if (index >= 0 && index < sizeof(colorTbl)/sizeof(DXFColor)) {
  132.         /*
  133.         ** return table entry
  134.         */
  135.         col.red = colorTbl[index].red;
  136.         col.green= colorTbl[index].green;
  137.         col.blue= colorTbl[index].blue;
  138.  
  139.         return (col);
  140.     }
  141.  
  142.     /*
  143.     ** Out-of-range color is white, like undefined.
  144.     */
  145.     col.red = 255;
  146.     col.green= 255;
  147.     col.blue= 255;
  148.                 
  149.     return (col);
  150. }
  151.  
  152. /********************************************************************\
  153. *                                                                    *
  154. * Name         : color2DXF                                           *
  155. *                                                                    *
  156. * Description  : Matches the nearest color available in the DXF      *
  157. *                color palette.                                      *
  158. *                                                                    *
  159. * Arguments    : red,green,blue : Color values.                      *
  160. *                                                                    *
  161. * Return Value : DXF color index.                                    *
  162. *                                                                    *
  163. * Comment      :                                                     *
  164. *                                                                    *
  165. \********************************************************************/
  166. static ULONG color2DXF (UBYTE red, UBYTE green, UBYTE blue)
  167. {
  168.     ULONG        i;
  169.     ULONG        index = 1;
  170.     DXFColor    current;
  171.     LONG        best;
  172.     LONG        difference;
  173.   
  174.     current = index2Color(index);
  175.     best =  magnitude(current.red-red,current.green-green,current.blue-blue);
  176.  
  177.     for (i = 0; i < sizeof(colorTbl)/sizeof(DXFColor); i++) {
  178.         current = index2Color(i);
  179.         difference = magnitude(current.red-red,current.green-green,current.blue-blue);
  180.         if (difference < best) {
  181.             best = difference;
  182.             index = i;
  183.         }
  184.     }
  185.  
  186.     return (index);
  187. }
  188.  
  189. /********************** Public functions ****************************/
  190.  
  191. /********************************************************************\
  192. *                                                                    *
  193. * Name         : write3DXF                                           *
  194. *                                                                    *
  195. * Description  : Writes a standart DXF ascii file.                   *
  196. *                                                                    *
  197. * Arguments    : dxffile IN  : An already opened file stream.        *
  198. *                mesh    IN  : Pointer to the mesh.                  *
  199. *                                                                    *
  200. * Return Value : RCNOERROR                                           *
  201. *                RCWRITEDATA                                         *
  202. *                                                                    *
  203. * Comment      :                                                     *
  204. *                                                                    *
  205. \********************************************************************/
  206. ULONG write3DXF(BPTR dxffile, TOCLMesh *mesh) {
  207.     UBYTE                         buffer[500];
  208.     TOCLVertex                    ver;
  209.     TOCLMaterialNode            *mat=NULL;
  210.     TOCLPolygonNode             *pln=NULL;
  211.     TOCLPolygonsVerticesNode    *plv=NULL;
  212.     ULONG l;
  213.  
  214.     /*
  215.     ** Write the header
  216.     */
  217.     if (FPuts(dxffile,"  0\nSECTION\n  2\nHEADER\n  9\n$ACADVER\n  1\nAC1009\n  0\nENDSEC\n")!=DOSFALSE) return(RCWRITEDATA);
  218.  
  219.     /*
  220.     ** Write the name and the copyright string if there are any
  221.     */
  222.     if (mesh->name!=NULL && mesh->name[0]!='\n') {
  223.         if (FPrintf(dxffile,"  0\n%s\n",mesh->name)==ENDSTREAMCH) return(RCWRITEDATA);
  224.     }
  225.     if (mesh->copyright!=NULL && mesh->copyright[0]!='\0') {
  226.         if (FPrintf(dxffile,"999\n%s\n",mesh->copyright)==ENDSTREAMCH) return(RCWRITEDATA);      
  227.     }
  228.  
  229.     /*
  230.     ** Begin the tables section and write the different materials as layers, an NOLAYERDEFINED layer with color WHITE will be defined for polygons without material
  231.     */
  232.     if (FPuts(dxffile,"  0\nSECTION\n  2\nTABLES\n  0\nTABLE\n  2\nLAYER\n 70\n2\n")!=DOSFALSE) return(RCWRITEDATA);
  233.     if (FPuts(dxffile,"  0\nLAYER\n  2\nNOLAYERDEFINED\n 70\n0\n 62\n7\n  6\nCONTINUOUS\n")!=DOSFALSE) return(RCWRITEDATA);    
  234.  
  235.     /* Write the materials */
  236.     if(mesh->materials.firstNode!=NULL) {
  237.           
  238.         /* The diffuse color is the only thing to translate */
  239.         mat=mesh->materials.firstNode;
  240.         do {
  241.             TOCLColor col=mat->diffuseColor;
  242.             
  243.             if (FPrintf(dxffile,"  0\nLAYER\n  2\n%s\n 70\n0\n 62\n%ld\n  6\nCONTINUOUS\n",mat->name,color2DXF(col.r,col.g,col.b))==ENDSTREAMCH) return(RCWRITEDATA);
  244.  
  245.             mat=mat->next;
  246.         } while(mat!=NULL);
  247.     }
  248.     if (FPuts(dxffile,"  0\nENDTAB\n  0\nENDSEC\n")!=DOSFALSE) return(RCWRITEDATA);
  249.  
  250.     /*
  251.     ** Write the entities section header
  252.     */
  253.     if(FPuts(dxffile,"  0\nSECTION\n  2\nENTITIES\n")!=DOSFALSE) return(RCWRITEDATA);
  254.  
  255.     /*
  256.     ** Write the polylines, if a polygon has no material a NOLAYERDEFINED layer will be used instead
  257.     */
  258.       if(mesh->polygons.firstNode!=NULL) {             
  259.             pln=mesh->polygons.firstNode;
  260.         do {                
  261.             if(pln->firstNode!=NULL) {                                                                              
  262.                 if(pln->numberOfVertices>=3) {    
  263.                     /* Check if there is a material */
  264.                     if (pln->materialNode!=NULL) {
  265.                         if (FPrintf(dxffile,"  0\nPOLYLINE\n  8\n%s\n 66\n1\n 70\n64\n 71\n%ld\n 72\n1\n",pln->materialNode->name,pln->numberOfVertices)==ENDSTREAMCH) return(RCWRITEDATA);
  266.                     } else {
  267.                         if (FPrintf(dxffile,"  0\nPOLYLINE\n  8\nNOLAYERDEFINED\n 66\n1\n 70\n64\n 71\n%ld\n 72\n1\n",pln->numberOfVertices)==ENDSTREAMCH) return(RCWRITEDATA);
  268.                     }
  269.                     /* First write the vertices */
  270.                     plv=pln->firstNode;
  271.                     do {
  272.                         ver=plv->vertexNode->vertex;
  273.                         /* Check if there is a material */
  274.                         if (pln->materialNode!=NULL) {
  275.                             sprintf(buffer,"  0\nVERTEX\n  8\n%s\n 10\n%g\n 20\n%g\n 30\n%g\n 70\n192\n",pln->materialNode->name,ver.x,ver.y,ver.z);
  276.                         } else {
  277.                             sprintf(buffer,"  0\nVERTEX\n  8\nNOLAYERDEFINED\n 10\n%g\n 20\n%g\n 30\n%g\n 70\n192\n",ver.x,ver.y,ver.z);
  278.                         }
  279.                         if(FPuts(dxffile,buffer)!=DOSFALSE) return(RCWRITEDATA);
  280.  
  281.                         plv=plv->next;
  282.                     } while(plv!=NULL);
  283.                     /* Second write the polyline connection vertices */                    
  284.                     for(l=2;l<pln->numberOfVertices;l++) {
  285.                         /* Check if there is a material */
  286.                         if (pln->materialNode!=NULL) {
  287.                             if (FPrintf(dxffile,"  0\nVERTEX\n  8\n%s\n 10\n0\n 20\n0\n 30\n0\n 70\n128\n 71\n1\n 72\n%ld\n 73\n%ld\n",pln->materialNode->name,l,l+1)==ENDSTREAMCH) return(RCWRITEDATA);
  288.                         } else {
  289.                             if (FPrintf(dxffile,"  0\nVERTEX\n  8\nNOLAYERDEFINED\n 10\n0\n 20\n0\n 30\n0\n 70\n128\n 71\n1\n 72\n%ld\n 73\n%ld\n",l,l+1)==ENDSTREAMCH) return(RCWRITEDATA);
  290.                         }
  291.                     }
  292.                     
  293.                     /* Write the end of the sequence */
  294.                     if (FPrintf(dxffile,"  0\nSEQEND\n")==ENDSTREAMCH) return(RCWRITEDATA);
  295.                 }
  296.             }
  297.             pln=pln->next;
  298.         } while(pln!=NULL);
  299.     }
  300.  
  301.     /*
  302.     ** Write the end of the file
  303.     */
  304.     if (FPrintf(dxffile,"  0\nENDSEC\n  0\nEOF\n")==ENDSTREAMCH) return(RCWRITEDATA);
  305.  
  306.     return(RCNOERROR);
  307. }
  308.  
  309. /************************* End of file ******************************/
  310.